#!/usr/bin/env python

# Based on libgpod examples.

import os.path
import sys
import gpod
from optparse import OptionParser

_covers = {}
def find_cover(filename):
    # DUPLICATED CODE: this is the same as in coverart-amazon and
    # ipod-music-set-coverart. KEEP IN SYNC!
    d = os.path.dirname(filename)
    try:
        return _covers[d]
    except KeyError:
        pass
    try:
        images = []
        for f in os.listdir(d):
            n, ext = os.path.splitext(f)
            if ext and ext[0] == '.':
                ext = ext[1:]
            n = n.lower()
            ext = ext.lower()
            if ext in ("jpg", "jpeg", "png"):
                path = os.path.join(d, f)
                if os.path.isfile(path):
                    images.append((path, n, ext))

        if not images:
            _covers[d] = None
            return None

        high_score_ext = ("jpg", "jpeg")
        def cover_cmp(a, b):
            a_p, a_n, a_e = a
            b_p, b_n, b_e = b

            if "front" in a_n:
                return -1
            elif "front" in b_n:
                return 1

            if "back" in a_n:
                return 1
            elif "back" in b_n:
                return -1

            if "cover" in a_n:
                return -1
            elif "cover" in b_n:
                return 1

            if a_e in high_score_ext:
                return -1
            elif b_e in high_score_ext:
                return 1
            return 0
        images.sort(cover_cmp)
        cover = _covers[d] = images[0][0]
        return cover

    except OSError:
        return None


parser = OptionParser(usage="usage: %prog [options]",
                      description="Add music and playlist to your ipod.",
                      epilog="Files are read from stdin, one per line.")
parser.add_option("-m", "--mountpoint", dest="mountpoint",
                  default="/mnt/ipod",
                  help="use iPod at MOUNTPOINT", metavar="MOUNTPOINT")
parser.add_option("-l", "--playlist", dest="playlist",
                  help="add tracks to PLAYLIST", metavar="PLAYLIST")
(options, args) = parser.parse_args()

db = gpod.Database(options.mountpoint)

playlist = None
if options.playlist:
    try:
        chosen_playlist = int(options.playlist)
    except ValueError:
        chosen_playlist = options.playlist

    for pl in db.Playlists:
        if pl.name == chosen_playlist:
            playlist = pl
    if not playlist:
        if isinstance(chosen_playlist, basestring):
            playlist = db.new_Playlist(title=chosen_playlist)
            print "Created new playlist %r" % (playlist,)
        else:
            raise ValueError("playlist id %d not found." % (chosen_playlist,))

_ipod_tracks = {}
for track in db:
    try:
        _ipod_tracks[track["userdata"]["filename_utf8"]] = track
    except:
        pass

for f in sys.stdin.readlines():
    if f[-1] == '\n':
        f = f[:-1]

    f = os.path.realpath(f)

    try:
        track = _ipod_tracks[f]
    except KeyError:
        try:
            track = db.new_Track(filename=f)
            _ipod_tracks[f] = track
        except gpod.TrackException, e:
            sys.stderr.write("ERROR: Could not add track %r: %s\n" % (f, e))
            continue

    if not track.get_coverart():
        cover = find_cover(f)
        if cover is not None:
            track.set_coverart_from_file(cover)

    if playlist is not None:
        if track not in playlist:
            playlist.add(track)

    print ("T: "
           "%r %r %r %r "
           "%d %d %r %r %r") % (
        f, track["artist"], track["album"], track["genre"],
        track["tracklen"], track["track_nr"], track["title"],
        bool(track.get_coverart()), bool(playlist))


progress_fmt = None
def progress(db, track, i, total):
    global progress_fmt
    if progress_fmt is None:
        progress_fmt = "Copying to iPod %%0%dd/%%d: %%s\r" % (len(str(total)),)
    sys.stdout.write(progress_fmt %
                     (i, total, track["userdata"]["filename_utf8"]))
    sys.stdout.flush()
print "Copying to iPod"
db.copy_delayed_files(callback=progress)
db.close()
